package Calculator.Parser;

import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import Calculator.Exceptions.DivisionByZeroException;
import Calculator.Parser.Elements.Operator;

public class RPNInterpreter {
	
	private Stack<Double> rpnStack;
	
	public RPNInterpreter() {
		rpnStack = new Stack<Double>();
	}

	/**
	 * Resuelve el cálculo 
	 * @param rpnString String en notación polaca inversa
	 * @return Resultado del cálculo
	 * @throws DivisionByZeroException
	 */
	public Double solve(String rpnString) throws DivisionByZeroException {
		Matcher elementsMatcher = Utilities.elementsPattern.matcher(rpnString);
		while (elementsMatcher.find()){
			if (this.matchesRegexp(elementsMatcher.group(1), Utilities.numberPattern)){
				this.rpnStack.push(new Double(elementsMatcher.group(1)));
			} else if(this.matchesRegexp(elementsMatcher.group(1), Utilities.operatorPattern)){
				Operator op = new Operator(elementsMatcher.group(1));
				Double x2 = this.rpnStack.pop();
				Double x1 = this.rpnStack.pop();
				Double result = op.operate(x1, x2);
				this.rpnStack.push(result);
			}
		}
		return this.rpnStack.pop();
	}

	private boolean matchesRegexp(String input, Pattern regexp) {
		Matcher operatorMatcher = regexp.matcher(input);
		return operatorMatcher.matches();
	}

}
